home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Mark Pilgrim / Jotto ][ 1.2 / source / Shell ƒ / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-30  |  11.0 KB  |  399 lines  |  [TEXT/MMCC]

  1. #include "main.h"
  2. #include "apple events.h"
  3. #include "integrity.h"
  4. #include "menus.h"
  5. #include "prefs.h"
  6. #include "environment.h"
  7. #include "error.h"
  8. #include "print meat.h"
  9. #include "sounds.h"
  10. #include "jotto.h"
  11. #include "graphics.h"
  12. #include "graphics dispatch.h"
  13. #include "window layer.h"
  14. #include "program globals.h"
  15. #include <AppleEvents.h>
  16. #include <EPPC.h>
  17.  
  18. static    short            gTheCurrentModifiers;
  19.  
  20. void main(void)
  21. {
  22.     Boolean            programIntegrityVerified;
  23.     Boolean            programIntegritySet;
  24.     
  25.     /* do integrity check before anything else; see integrity.c for details */
  26.     programIntegrityVerified=DoIntegrityCheck(&programIntegritySet);
  27.     
  28.     /* standard program initialization stuff */
  29.     MaxApplZone();    
  30.     InitGraf(&qd.thePort);
  31.     InitFonts();
  32.     FlushEvents(everyEvent, 0);
  33.     InitWindows();
  34.     InitMenus();
  35.     TEInit();
  36.     InitDialogs(0L);
  37.     InitCursor();
  38.     GetDateTime((unsigned long*)&qd.randSeed);
  39.     
  40.     InitTheWindowLayer();
  41.     
  42.     if (!InitTheEnvironment())            /* gestalt checks and variable initialization */
  43.         HandleError(kSystemTooOld, TRUE);        /* less than system 4.1 */
  44.     
  45.     if (!programIntegrityVerified)    /* integrity check failed */
  46.         HandleError(kProgramIntegrityNotVerified, TRUE);
  47.     
  48.     if (programIntegritySet)    /* integrity check freshly installed */
  49.         HandleError(kProgramIntegritySet, FALSE);
  50.     
  51.     InitTheSounds();                /* see if sound is available, etc. */
  52.     
  53.     PrefsError(PreferencesInit());    /* get prefs (create if necessary) */
  54.     
  55.     if (!InitTheMenus())        /* get menus from .rsrc and draw menu bar */
  56.         HandleError(kProgramIntegrityNotVerified, TRUE);
  57.         
  58.     InitThePrinting();
  59.     
  60.     InitTheProgram();
  61.     
  62.     EventLoop();                    /* where it all happens (see below) */
  63.     
  64.     ShutDownEnvironment(TRUE);        /* where it all ends (see below) */
  65.     
  66.     ExitToShell();
  67. }
  68.  
  69. void EventLoop(void)
  70. {
  71.     while (!gDone)    /* gDone set by choosing "Quit" menu item or by "quit" apple event */
  72.         HandleSingleEvent(TRUE);
  73. }
  74.  
  75. Boolean HandleSingleEvent(Boolean allowContextSwitching)
  76. {
  77.     EventRecord        theEvent;
  78.     WindowPtr        front;
  79.     
  80.     if (!gCustomCursor)
  81.         SetCursor(&qd.arrow);
  82.     HiliteMenu(0);            /* normalize menubar */
  83.     
  84.     gFrontWindowIndex=0;
  85.     gFrontWindowIsOurs=FALSE;
  86.     front=FrontWindow();
  87.     if (front!=0L)    /* if there's a front window, see if it's one of ours */
  88.     {
  89.         if (WindowHasLayer(front))
  90.         {
  91.             SetPort(front);
  92.             gFrontWindowIsOurs=TRUE;
  93.             gFrontWindowIndex=GetWindowIndex(front);
  94.         }
  95.     }
  96.         
  97.     /* get an event from the queue */
  98.     WaitNextEvent(everyEvent, &theEvent, gIsInBackground ? gBackgroundWaitTime : gForegroundWaitTime, 0L);
  99.     gTheCurrentModifiers=theEvent.modifiers;
  100.     
  101.     DispatchEvents(theEvent, allowContextSwitching);    /* handle the event we just got */
  102.     
  103.     return (theEvent.what!=nullEvent);
  104. }
  105.  
  106. short GetTheModifiers(void)
  107. {
  108.     return gTheCurrentModifiers;
  109. }
  110.  
  111. void DispatchEvents(EventRecord theEvent, Boolean allowContextSwitching)
  112. {
  113.     Point            thisPoint;
  114.     short            index;
  115.     WindowPtr        theWindow;
  116.     Boolean            thisWindowIsOurs;
  117.     unsigned char    theChar;
  118.     
  119.     thisWindowIsOurs=FALSE;
  120.     /* for update/activate events, see if the window in question is one of ours */
  121.     if ((theEvent.what==activateEvt) || (theEvent.what==updateEvt))
  122.     {
  123.         thisWindowIsOurs=WindowHasLayer((WindowPtr)theEvent.message);
  124.         if (thisWindowIsOurs)
  125.             index=GetWindowIndex((WindowPtr)theEvent.message);
  126.     }
  127.     else if (gFrontWindowIsOurs)    /* if front window is ours, get its window index */
  128.         index=gFrontWindowIndex;
  129.     else index=-1;
  130.     
  131.     switch (theEvent.what)
  132.     {
  133.         case nullEvent:    /* ain't nuthin' happenin' */
  134.             if ((gSoundAvailable) && (gSoundIsFinishedPlaying))
  135.                 CloseTheSoundChannel();
  136.             
  137.             if (gKludgeIter<3)
  138.             {
  139.                 gKludgeIter++;
  140.             }
  141.             else
  142.             {
  143.                 if (gNeedToOpenWindow)
  144.                 {
  145.                     NewGame();
  146.                     gNeedToOpenWindow=FALSE;
  147.                 }
  148.             }
  149.             
  150.             if (gFrontWindowIsOurs)        /* give control to window dispatch to handle null */
  151.             {
  152.                 thisPoint=theEvent.where;
  153.                 GlobalToLocal(&thisPoint);
  154.                 theWindow=FrontWindow();
  155.                 if ((WindowHasLayer(theWindow)) && (WindowIsFloat(theWindow)))
  156.                 {
  157.                     if (IdleWindowDispatch(index, thisPoint)==kPassThrough)
  158.                     {
  159.                         if ((theWindow=GetFrontDocumentWindow())!=0L)
  160.                         {
  161.                             index=GetWindowIndex(theWindow);
  162.                             SetPort(theWindow);
  163.                             thisPoint=theEvent.where;
  164.                             GlobalToLocal(&thisPoint);
  165.                             IdleWindowDispatch(index, thisPoint);
  166.                         }
  167.                     }
  168.                 }
  169.                 else
  170.                 {
  171.                     IdleWindowDispatch(index, thisPoint);
  172.                 }
  173.             }
  174.             break;
  175.         case mouseDown:    /* mouse button pressed */
  176.             HandleMouseDown(theEvent, allowContextSwitching);    /* see below for mousedown handling */
  177.             break;
  178.         case keyDown:    /* key pressed */
  179.         case autoKey:    /* key help down */
  180.             theChar=(unsigned char)(theEvent.message & charCodeMask);
  181.             
  182.             if (theEvent.modifiers & cmdKey)    /* handle as command-key equivalent */
  183.             {
  184.                 AdjustMenus();    /* just to be safe */
  185.                 HandleMenu(MenuKey(theChar));
  186.             }
  187.             else if (gFrontWindowIsOurs)    /* --> window's dispatch for keydown */
  188.             {
  189.                 theWindow=FrontWindow();
  190.                 if ((WindowHasLayer(theWindow)) && (WindowIsFloat(theWindow)))
  191.                 {
  192.                     if (KeyDownDispatch(index, theChar)==kPassThrough)
  193.                     {
  194.                         if ((theWindow=GetFrontDocumentWindow())!=0L)
  195.                         {
  196.                             index=GetWindowIndex(theWindow);
  197.                             KeyDownDispatch(index, theChar);
  198.                         }
  199.                     }
  200.                 }
  201.                 else
  202.                 {
  203.                     KeyDownDispatch(index, theChar);
  204.                 }
  205.             }
  206.             break;
  207.         case diskEvt:    /* disk insert */
  208.             if (HiWord(theEvent.message)!=noErr)    /* bad disk inserted */
  209.             {
  210.                 DILoad();    /* load disk initialization package */
  211.                 SetPt(&thisPoint, 120, 120);
  212.                 DIBadMount(thisPoint, theEvent.message);    /* give format? dialog */
  213.                 DIUnload();    /* unload 'cuz we certainly don't need it */
  214.             }
  215.             break;
  216.         case updateEvt:    /* window update */
  217.             theWindow=(WindowPtr)theEvent.message;    /* which window? */
  218.             
  219.             BeginUpdate(theWindow);        /* means: "OK, we're dealing with this now" */
  220.             
  221.             if (thisWindowIsOurs)        /* one of ours?  see graphics.c */
  222.                 UpdateTheWindow(theWindow);
  223.             
  224.             EndUpdate(theWindow);        /* means: "OK, we're done updating now" */
  225.             break;
  226.         case activateEvt:    /* window activate or deactivate */
  227.             if (thisWindowIsOurs)        /* one of ours?  send message to window dispatch */
  228.             {
  229.                 if (gIgnoreNextActivateEvent)
  230.                     gIgnoreNextActivateEvent=FALSE;
  231.                 else
  232.                 {
  233.                     if ((theEvent.modifiers & activeFlag)!=0)
  234.                         ActivateWindowDispatch(index);
  235.                     else
  236.                         DeactivateWindowDispatch(index);
  237.                 }
  238.             }
  239.             break;
  240.         case osEvt:            /* suspend or resume program execution (switch in/out) */
  241.             if (((theEvent.message>>24)&0x0FF)==suspendResumeMessage)
  242.             {
  243.                 /* keep track of whether we're in the background or foreground */
  244.                 gIsInBackground=((theEvent.message&resumeFlag)==0);
  245.                 
  246.                 if (gFrontWindowIsOurs)        /* send activate/deactivate to front window */
  247.                 {
  248.                     if (gIsInBackground)
  249.                         DeactivateWindowDispatch(index);
  250.                     else
  251.                         ActivateWindowDispatch(index);
  252.                 }
  253.                 
  254.                 /* if we just came into the foreground and we have a pending error,
  255.                    now's the time to display it */
  256.                 if ((!gIsInBackground) && (gPendingResultCode!=allsWell))
  257.                 {
  258.                     if (gHasNotificationManager)
  259.                         NMRemove(&gMyNotification);        /* remove notification request */
  260.                     HandleError(gPendingResultCode, FALSE);    /* display alert, see error.c */
  261.                     gPendingResultCode=allsWell;        /* ...now it is */
  262.                 }
  263.             }
  264.             break;
  265.         case kHighLevelEvent:    /* apple event */
  266.             AEProcessAppleEvent(&theEvent);        /* see apple events.c */
  267.             break;
  268.     }
  269. }
  270.  
  271. void HandleMouseDown(EventRecord theEvent, Boolean allowContextSwitching)
  272. {
  273.     WindowPtr        theWindow;
  274.     short            windowCode;
  275.     long            windSize;
  276.     GrafPtr            oldPort;
  277.     Rect            sizeRect;
  278.     short            index;
  279.     Point            theLocalPoint;
  280.     Boolean            thisWindowIsOurs;
  281.     long            mSelect;
  282.     
  283.     windowCode=FindWindow(theEvent.where, &theWindow);    /* which window? */
  284.  
  285.     thisWindowIsOurs=FALSE;
  286.     thisWindowIsOurs=WindowHasLayer(theWindow);
  287.     if ((thisWindowIsOurs=WindowHasLayer(theWindow))==TRUE)
  288.         index=GetWindowIndex(theWindow);
  289.     else
  290.         index=-1;
  291.     
  292.     switch (windowCode)
  293.     {
  294.         case inMenuBar:        /* in menu bar; let system take over */
  295.             AdjustMenus();
  296.             mSelect=MenuSelect(theEvent.where);
  297. //            mSelect=ManualMenuSelect(2);
  298.             HandleMenu(mSelect);
  299.             break;
  300.         case inContent:        /* in window content */
  301.             if (!MySelectWindow(theWindow))        /* didn't need to change front windows */
  302.             {
  303.                 if (gFrontWindowIsOurs)    /* inform window dispatch of mousedown */
  304.                 {
  305.                     theLocalPoint=theEvent.where;
  306.                     SetPort(theWindow);
  307.                     GlobalToLocal(&theLocalPoint);
  308.                     MouseDownDispatch(index, theLocalPoint);
  309.                 }
  310.             }
  311.             break;
  312.         case inSysWindow:    /* in system window (desk accessory) */
  313.             if (allowContextSwitching)
  314.                 SystemClick(&theEvent, theWindow);    /* let the system deal with it */
  315.             break;
  316.         case inDrag:        /* in drag _region_, that is */
  317.             /* the accepted way to draw a window */
  318.             DragWindow(theWindow, theEvent.where, &((**GetGrayRgn()).rgnBBox));
  319.             if (thisWindowIsOurs)    /* update window bounds in window data struct */
  320.             {
  321.                 SetWindowBounds(theWindow,
  322.                     (*(((WindowPeek)theWindow)->contRgn))->rgnBBox);
  323.                 theLocalPoint.v=GetWindowBounds(theWindow).top;
  324.                 theLocalPoint.h=GetWindowBounds(theWindow).left;
  325.                 SetWindowTopLeft(theWindow, theLocalPoint);
  326.                 MySelectWindow(theWindow);
  327.             }
  328.             break;
  329.         case inGoAway:        /* close box */
  330.             /* the accepted way to track a close box attempt */
  331.             if (TrackGoAway(theWindow, theEvent.where))
  332.                 DoTheCloseThing((WindowPeek)theWindow);        /* see menus.c */
  333.             break;
  334.         case inGrow:        /* grow box */
  335.             /* the accepted way to grow a window */
  336.             if (thisWindowIsOurs)
  337.             {
  338.                 if (GetGrowSizeDispatch(index, &sizeRect)==kFailure)
  339.                     sizeRect=qd.screenBits.bounds;
  340.             }
  341.             else sizeRect=qd.screenBits.bounds;
  342.             
  343.             windSize=GrowWindow(theWindow, theEvent.where, &sizeRect);
  344.             if (windSize!=0)
  345.             {
  346.                 GetPort(&oldPort);
  347.                 SetPort(theWindow);
  348.                 EraseRect(&theWindow->portRect);
  349.                 SizeWindow(theWindow, LoWord(windSize), HiWord(windSize), TRUE);
  350.                 InvalRect(&theWindow->portRect);
  351.                 SetPort(oldPort);
  352.                 
  353.                 if (thisWindowIsOurs)    /* update window bounds in window data struct */
  354.                 {
  355.                     GrowWindowDispatch(index);
  356.                     SetWindowBounds(theWindow,
  357.                         (*(((WindowPeek)theWindow)->contRgn))->rgnBBox);
  358.                     theLocalPoint.v=GetWindowBounds(theWindow).top;
  359.                     theLocalPoint.h=GetWindowBounds(theWindow).left;
  360.                     SetWindowTopLeft(theWindow, theLocalPoint);
  361.                 }
  362.             }
  363.             break;
  364.         case inZoomIn:        /* zoom box */
  365.         case inZoomOut:
  366.             /* the accepted way to track a zoom attempt */
  367.             if (TrackBox(theWindow, theEvent.where, windowCode))
  368.             {
  369.                 GetPort(&oldPort);
  370.                 SetPort(theWindow);
  371.                 ZoomWindow(theWindow, windowCode, FALSE);
  372.                 InvalRect(&theWindow->portRect);
  373.                 SetPort(oldPort);
  374.             }
  375.             
  376.             if (thisWindowIsOurs)    /* update window bounds in window data struct */
  377.             {
  378.                 ZoomWindowDispatch(index);
  379.                 SetWindowBounds(theWindow,
  380.                     (*(((WindowPeek)theWindow)->contRgn))->rgnBBox);
  381.                 theLocalPoint.v=GetWindowBounds(theWindow).top;
  382.                 theLocalPoint.h=GetWindowBounds(theWindow).left;
  383.                 SetWindowTopLeft(theWindow, theLocalPoint);
  384.             }
  385.             break;
  386.     }
  387. }
  388.  
  389. void ShutDownEnvironment(Boolean fullShutdown)
  390. {
  391.     SaveThePrefs();
  392.     if (fullShutdown)
  393.     {
  394.         ShutDownTheProgram();        /* program-specific cleanup */
  395.         ShutDownTheWindowLayer();    /* do shutdown dispatch for all windows we've used */
  396.         ShutDownTheMenus();            /* release menu resources */
  397.     }
  398. }
  399.